package com.tally.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Administrator
 * @desc: 身份信息加密、手机号码校验工具类
 */
public class CodeUtils {
    /**
     * 中国电信号码格式验证 手机段： 133,149,153,173,177,180,181,189,191,199,1349,1410,1700,1701,1702
     **/
    private static final String CHINA_TELECOM_PATTERN = "(?:^(?:\\+86)?1(?:33|49|53|7[37]|8[019]|9[19])\\d{8}$)|(?:^(?:\\+86)?1349\\d{7}$)|(?:^(?:\\+86)?1410\\d{7}$)|(?:^(?:\\+86)?170[0-2]\\d{7}$)";

    /**
     * 中国联通号码格式验证 手机段：130,131,132,145,146,155,156,166,171,175,176,185,186,1704,1707,1708,1709
     **/
    private static final String CHINA_UNICOM_PATTERN = "(?:^(?:\\+86)?1(?:3[0-2]|4[56]|5[56]|66|7[156]|8[56])\\d{8}$)|(?:^(?:\\+86)?170[47-9]\\d{7}$)";

    /**
     * 中国移动号码格式验证
     * 手机段：134,135,136,137,138,139,147,148,150,151,152,157,158,159,172，178,182,183,184,187,188,195,198,1440,1703,1705,1706
     **/
    private static final String CHINA_MOBILE_PATTERN = "(?:^(?:\\+86)?1(?:3[4-9]|4[78]|5[0-27-9]|72|78|8[2-478]|98|95)\\d{8}$)|(?:^(?:\\+86)?1440\\d{7}$)|(?:^(?:\\+86)?170[356]\\d{7}$)";

    /***
     * 验证是否是虚拟电话号码 17[0,1]，16[2,5,7]
     * @param phoneNo
     * @return
     */
    public static boolean verificationPhone(String phoneNo){
        Pattern pattern = Pattern.compile("^((17[0-1])|(16[2,5,7]))\\d{8}$");
        Matcher matcher = pattern.matcher(phoneNo);
        return matcher.matches();
    }


    /**
     * 中国大陆手机号码校验
     *
     * @param phone
     *
     * @return
     */
    public static boolean checkPhone(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            if (checkChinaMobile(phone) || checkChinaUnicom(phone) || checkChinaTelecom(phone)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 中国移动手机号码校验
     *
     * @param phone
     *
     * @return
     */
    public static boolean checkChinaMobile(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            Pattern regexp = Pattern.compile(CHINA_MOBILE_PATTERN);
            if (regexp.matcher(phone).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 中国联通手机号码校验
     *
     * @param phone
     *
     * @return
     */
    public static boolean checkChinaUnicom(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            Pattern regexp = Pattern.compile(CHINA_UNICOM_PATTERN);
            if (regexp.matcher(phone).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 中国电信手机号码校验
     *
     * @param phone
     *
     * @return
     */
    public static boolean checkChinaTelecom(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            Pattern regexp = Pattern.compile(CHINA_TELECOM_PATTERN);
            if (regexp.matcher(phone).matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验邮箱格式
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        if (filterEmoji(email)){
            return false;
        }
        //判断是否为空邮箱
        int k = 0;
        if(email == null|| email=="") {
            return false;
        }
        /**
         * 单引号引的数据
         * 是char类型的双引号引的数据
         * 是String类型的单引号只能引一个字符而双引号可以引0个及其以上
         */
        //判断是否有仅有一个@且不能在开头或结尾
        if(email.indexOf("@") > 0 && email.indexOf('@') == email.lastIndexOf('@') && email.indexOf('@') < email.length()-1) {
            k++;
        }
        //判断"@"之后必须有"."且不能紧跟
        if(email.indexOf('.',email.indexOf('@')) > email.indexOf('@')+1 ) {
            k++;
        }
        //判断"@"之前或之后不能紧跟"."
        if(email.indexOf('.') < email.indexOf('@')-1 || email.indexOf('.') > email.indexOf('@')+1 ) {
            k++;
        }
        //@之前要有6个字符
        if(email.indexOf('@') > 5 ) {
            k++;
        }
        if(email.endsWith("com") || email.endsWith("org") || email.endsWith("cn") ||email.endsWith("net")) {
            k++;
        }
        if(k == 5) {
            return true;
        }
        return false;
    }

    /**
     * 校验字符串中是否包含表情
     * @param source
     * @return
     */
    public static Boolean filterEmoji(String source) {
        Pattern emoji = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        Matcher emojiMatcher = emoji.matcher(source);
        if (emojiMatcher.find()) {
            return true;
        }
        return false;
    }

    /**
     * 用户姓名的打码隐藏加星号加*
     * 名字是两位时: 张三--> *三
     * 名字是三位及以上时: 燕双鹰 --> 燕*鹰
     * @return 处理完成的姓名
     */
    public static String nameMask(String name){
        String res = "";
        if (name.length() == 2){
            res = name.replaceAll("^.", "*");
        }else if (name.length() > 2){
            res = name.replaceAll("(?<=.).(?=.)", "*");
        }
        return res;
    }

    /**
     * 用户身份证号码的打码隐藏加星号加*
     * @return 处理完成的身份证
     */
    public static String idCardMask(String idCardNum) {
        String res = "";
        if (!StringUtils.isEmpty(idCardNum)) {
            StringBuilder stringBuilder = new StringBuilder(idCardNum);
            res = stringBuilder.replace(6, 14, "********").toString();
        }
        return res;
    }

    /**
     * 用户电话号码的打码隐藏加星号加*
     * @return 处理完成电话号码
     */
    public static String phoneMask(String phone) {
        String res = "";
        if (!StringUtils.isEmpty(phone)) {
            StringBuilder stringBuilder = new StringBuilder(phone);
            res = stringBuilder.replace(3, 7, "****").toString();
        }
        return res;
    }

    /**
     * 生成指定位数验证码,纯数字运算效率最高
     * @param maxSize
     * @return
     */
    public static Long generateRandomCode(int maxSize) {
        if (maxSize < 0) {
            maxSize = 6;
        }
        //小数点后16位的double乘以10的指定次幂然后取整
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, maxSize - 1)));
        Long resultCode = Long.valueOf(code);
        return resultCode;
    }



}
